/*
 * Copyright 2005-2013 finalist.cn. All rights reserved.
 * Support: http://www.finalist.cn
 * License: http://www.finalist.cn/license
 */
package com.finalist.controller.travel.pc;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.finalist.Mail;
import com.finalist.Setting;
import com.finalist.Setting.CaptchaType;
import com.finalist.controller.admin.BaseController;
import com.finalist.entity.Admin;
import com.finalist.entity.Product;
import com.finalist.entity.Role;
import com.finalist.plugin.StoragePlugin;
import com.finalist.service.AdminService;
import com.finalist.service.CaptchaService;
import com.finalist.service.DepartureService;
import com.finalist.service.DestinationService;
import com.finalist.service.MailService;
import com.finalist.service.MemberService;
import com.finalist.service.ProductCategoryService;
import com.finalist.service.ProductService;
import com.finalist.util.DateUtil;
import com.finalist.util.FreemarkerUtils;
import com.finalist.util.SettingUtils;
import com.finalist.util.ZXingUtil.ZXingUtil;
import com.finalist.vo.ImageFile;
import com.finalist.vo.ProductResult;
import com.finalist.vo.RegisterResult;

import sun.misc.BASE64Encoder;

/**
 * Controller - 首页
 * 
 * @author Finalist IT Group
 * @version 3.0
 */
@Controller("indexController")
@RequestMapping("/travel/pc/index")
public class IndexController extends BaseController {
	
	@Resource(name = "productServiceImpl")
	private ProductService productService;

	@Resource(name = "productCategoryServiceImpl")
	private ProductCategoryService productCategoryService;

	@Resource(name = "destinationServiceImpl")
	private DestinationService destinationService;

	@Resource(name = "departureServiceImpl")
	private DepartureService departureService;
	
	@Resource(name = "captchaServiceImpl")
	private CaptchaService captchaService;
	
	@Resource(name = "memberServiceImpl")
	private MemberService memberService;
	
	@Resource
	private List<StoragePlugin> storagePlugins;
	

	protected static final String VIEW = "/travel/pc/";
	
	/** 默认"验证ID"参数名称 */
	private static final String DEFAULT_CAPTCHA_ID_PARAM = "captchaId";
	
	/** 默认"验证码"参数名称 */
	private static final String DEFAULT_CAPTCHA_PARAM = "captcha";
	
	/** "验证ID"参数名称 */
	private String captchaIdParam = DEFAULT_CAPTCHA_ID_PARAM;
	
	/** "验证码"参数名称 */
	private String captchaParam = DEFAULT_CAPTCHA_PARAM;
	
	@Resource(name ="adminServiceImpl")
	private AdminService adminService;
	
	private final static byte[] keyBytes = new byte[] {
		 (byte) 0x2b,(byte) 0x3b, (byte) 0x99, (byte) 0x39,
		 (byte) 0xfa,(byte) 0x3a, (byte) 0x56, (byte) 0xab,
		 (byte) 0x9d, (byte) 0xf8, (byte) 0xd7, (byte) 0xcd,
		 (byte) 0x50, (byte) 0x8e, (byte) 0xf9, (byte) 0xff,
		 };

	/**
	 * 首页
	 */
	@RequestMapping(value = "/show", method = RequestMethod.GET)
	public String index(HttpServletRequest request,ModelMap model) {
		
		//通过request获取项目实际运行目录,就可以将上传文件存放在项目目录了,不管项目部署在任何地方都可以
		String realPath = request.getSession().getServletContext().getRealPath("/");
		String logoPath = realPath+"resources\\travel\\pc\\assets\\img\\Fengke_logo.png";
		String content;
		String dest;
		
		SimpleDateFormat df = new SimpleDateFormat("yyyyMM");//设置日期格式
		String date = df.format(new Date());
		
		List<Product> carouselProductsTemp = productService.findProductByCondition(1, true, true, null, null, null, null, null);
		if(carouselProductsTemp != null && carouselProductsTemp.size()>0){
			Product carouselProducts = carouselProductsTemp.get(0);
			model.put("carouselProducts", carouselProducts);
		}
		
		/*model.put("products", productService.findProductByPage(1));*/
		model.put("categorys", productCategoryService.findAll());
		model.put("destinations", destinationService.findAll());
		model.put("departures", departureService.findAll());
		model.put("dates", getDates());
		
		model.addAttribute("activePage", "index");
		
		try {
			//List<Product> products = productService.findProductByCondition(page, true, null, null, null, null, null, null);
			Integer pageNo = 1;
			List<Product> AllProducts = productService.findPCProductByPage(pageNo, true, 10000, null, null, null, null, null);
			
			for (Iterator iter = AllProducts.iterator(); iter.hasNext(); ) {
				Product product = (Product)iter.next();
				int productId = new Long(product.getId()).intValue();
				
				content = "http://fengkeworld.com/travel/weixin/product/detail.jhtml?productId="+productId;
				//dest = realPath+"upload\\image\\zxing\\Fengke_productId_"+productId+"_Index.png";
				//dest = "\\root\\data\\fengke\\zxing\\"+date+"\\Fengke_productId_"+productId+"_Index.png";
				
				dest = "/root/data/fengke/picture/zxing/"+date+"/Fengke_productId_"+productId+"_Index.png";
				
				ZXingUtil.generateCodeImg(content, 300, 300, dest, logoPath);
				
				product.setZxingPath(dest);
				productService.update(product);
			}
			
			List<Product> products = productService.findPCProductByPage(pageNo, true, 12, null, null, null, null, null);
			model.addAttribute("products", products);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "/shop/index";
	}
	
	public List<String> getDates(){
		List<String> dates =  new ArrayList<String>(); 
		Date now = new Date();
		for(int i = 0 ; i< 12 ; i++){
			dates.add(DateUtil.getYear(DateUtil.addMonth(now, i))+"-"+DateUtil.getMonth(DateUtil.addMonth(now, i)));
		}
		return dates;
	}
	
	/**
	 * ajax查询
	 */
	@RequestMapping(value = "/ajaxProduct" , method = RequestMethod.GET)
	@ResponseBody
	public ProductResult ajaxProduct(HttpServletRequest re,Long[] theme , String[] fromwhere , String[] towhere,String[] when,String[] howlong,Integer page){
		//List<Product> products = productService.findProductByCondition(page, true, null, theme, fromwhere, towhere, when, howlong);
		int pageSize;
		if(page == 1){
			pageSize = 10000;
		}else{
			pageSize = 12;
		}
		
		List<Product> products = productService.findPCProductByPage(page, true, pageSize, theme, fromwhere, towhere, when, howlong);
		ProductResult result = new ProductResult();
		if(page == 1 && (products==null || products.size() == 0)){
			result.setType("noAll");
			List<Product> _products = null;
			switch (0) {
			case 0:
				if(theme==null || theme.length == 0){
				}else{
					//_products = productService.findProductByCondition(1, true, null, theme, null, null, null, null);
					_products = productService.findPCProductByPage(1, true, pageSize, theme, null, null, null, null);
					if(_products!=null && _products.size()!=0){
						result.setProducts(_products);
						return result;
					}
				}
			case 1:
				if(fromwhere==null || fromwhere.length == 0){
				}else{
					//_products = productService.findProductByCondition(1, true, null, null, fromwhere, null, null, null);
					_products = productService.findPCProductByPage(1, true, pageSize, null, fromwhere, null, null, null);
					if(_products!=null &&_products.size()!=0){
						result.setProducts(_products);
						return result;
					}
				}
			case 2:
				if(towhere==null || towhere.length == 0){
				}else{
					//_products = productService.findProductByCondition(1, true, null, null, null, towhere, null, null);
					_products = productService.findPCProductByPage(1, true, pageSize, null, null, towhere, null, null);
					if(_products!=null && _products.size()!=0){
						result.setProducts(_products);
						return result;
					}
				}
			case 3:
				if(when==null || when.length == 0){
				}else{
					//_products = productService.findProductByCondition(1, true, null, null, null, null, when, null);
					_products = productService.findPCProductByPage(1, true, pageSize, null, null, null, when, null);
					if(_products!=null &&_products.size()!=0){
						result.setProducts(_products);
						return result;
					}
				}
			case 4:
				if(howlong==null || howlong.length == 0){
				}else{
					//_products = productService.findProductByCondition(1, true, null, null, null, null, null, howlong);
					_products = productService.findPCProductByPage(1, true, pageSize, null, null, null, null, howlong);
					if(_products!=null &&_products.size()!=0){
						result.setProducts(_products);
						return result;
					}
				}
			default:
				result.setType("isNull");
				result.setProducts(null);
				return result;
			}
		}else{
			result.setType("all");
			result.setProducts(products);
			return result;
		}
	}

	@RequestMapping("/login")
	public String login(ModelMap model) {
		return VIEW + "login";
	}
	@RequestMapping("/authLogin")
	@ResponseBody
	public RegisterResult authLogin(String account,String password,ModelMap model) {
		RegisterResult result = new RegisterResult();
		Admin admin = adminService.findByUsername(account);
		if(admin==null){
			result.setType("error");
			result.setContent("用户不存在");
			return result;
		}
		if(!DigestUtils.md5Hex(password).equals(admin.getPassword())){
			result.setType("error");
			result.setContent("用户密码错误");
			return result;
		}
		if(admin.getIsEnabled()){
		}
		return null;
	}

	@RequestMapping("/register")
	public String register(Long id,ModelMap model) {
		String captchaId = UUID.randomUUID().toString();
		model.put("captchaId", captchaId);
		Admin admin = adminService.find(id);
		if(admin!=null){
			model.put("admin", admin);
			if(!admin.getIsCheck()){
				
				if(admin.getStep()==4 && !StringUtils.isNotBlank(admin.getReason())){
					//正在审核中
					model.put("type", "checking");
					model.put("redirect", "false");
				}else if(admin.getStep()==4 && StringUtils.isNotBlank(admin.getReason())){
					//审核不通过
					model.put("type", "notPass");
					model.put("redirect", "false");
				}else if(admin.getStep() < 4){
					model.put("type", "unfinished");
					model.put("redirect", "false");
					//资料未填写完毕
				}
			}else{
				model.put("type", "pass");
				model.put("redirect", "false");
			}
		}
		return VIEW + "register";
	}
	
	
	/**
	 * 邮箱注册步
	 * @param request
	 * @param admin
	 * @param model
	 * @return
	 */
	@RequestMapping("/stepOne")
	@ResponseBody
	public RegisterResult registerStepOne(HttpServletRequest request,Admin admin, ModelMap model) {
		RegisterResult result = new RegisterResult();
		try {
			String captchaId = getCaptchaId(request);
			String captcha = getCaptcha(request);
			if(!captchaService.isValid(CaptchaType.adminLogin, captchaId, captcha)){
				result.setType("error");
				result.setContent("验证码错误");
				return result;
			}
			admin.setIsEnabled(true); //注册默认账号为启用
			admin.setIsLocked(false);
			admin.setLoginFailureCount(0);
			admin.setLockedDate(null);
			admin.setLoginDate(null);
			admin.setLoginIp(null);
			admin.setOrders(null);
			admin.setAddress("system");
			admin.setPhoneNum("system");
			admin.setCompany("system");
			admin.setHasCheck(false);
			admin.setPaperNum("system");
			admin.setIdNum("system");
			admin.setIdFrontImg("system");
			admin.setIdBackImg("system");
			admin.setIdHandsImg("system");
			admin.setStep(1);
			admin.setPassword(DigestUtils.md5Hex(admin.getPassword()));
			admin.setHasEmailAction(false);
			admin.setTicket(encryptionTicket(admin.getEmail()+new Date().getTime()).replaceAll("\\+", "_"));
			admin.setRegisterTime(new Date());
			if(admin.getId()==null || admin.getId() <=0){
				admin.setId(null);
				adminService.save(admin);
				Admin persist =  adminService.findByUsername(admin.getUsername());
				result.setType("succ");
				result.setContent("注册成功");
				result.setAdminId(persist.getId());
				admin.setId(persist.getId());
				sendEmail(admin);
				return result;
			}else{
				adminService.update(admin);
				sendEmail(admin);
				result.setType("succ");
				result.setContent("注册成功");
				result.setAdminId(admin.getId());
				return result;
			}
		} catch (Exception e) {
			result.setType("error");
			result.setContent("服务器错误");
			e.printStackTrace();
			return result;
		}
	}
	
	/**
	 * 重新发送邮箱
	 * @param request
	 * @param adminId
	 * @param model
	 * @return
	 */
	@RequestMapping("/reSendEmail")
	@ResponseBody
	public RegisterResult reSendEmail(HttpServletRequest request,Long adminId, ModelMap model){
		RegisterResult result = new RegisterResult();
		Admin admin = adminService.find(adminId);
		if(admin.getStep()>1 || admin.isHasEmailAction()){
			//商户已经激活了
			result.setType("error");
			result.setContent("邮箱已经激活!无法发送");
		}else{
			String ticket = encryptionTicket(admin.getEmail()+new Date().getTime()).replaceAll("\\+", "_");
			admin.setTicket(ticket);
			admin.setRegisterTime(new Date());
			adminService.update(admin);
			sendEmail(admin);
			result.setType("succ");
			result.setContent("发送成功");
		}
		return result;
	}
	
	/**
	 * 邮箱激活
	 * @param id
	 * @param Ticket
	 * @param model
	 * @return
	 */
	@RequestMapping("/actionEmail")
	public String actionEmail(String id,String Ticket, ModelMap model) {
		Admin admin = adminService.find(Long.valueOf(id));
		if(admin==null){
			model.put("operateType", "actionEmail");
			model.put("operateResult", "error");
			model.put("content","未找到数据，请重新注册!");
		}else if(!Ticket.equals(admin.getTicket())){
			model.put("operateType", "actionEmail");
			model.put("operateResult", "error");
			model.put("content","认证错误!");
		}else if(admin.getTicket().equals(Ticket)){
			if((new Date().getTime() - admin.getRegisterTime().getTime())>48*60*60*1000){
				model.put("operateType", "actionEmail");
				model.put("operateResult", "error");
				model.put("content","该链接已失效，请重新操作!");
			}else{
				if(admin.getStep()==1 && !admin.isHasEmailAction()){
					adminService.updateActionEamil(admin.getId());
					admin.setStep(2);
					model.put("type", "unfinished");
					model.put("admin", admin);
				}else{//说明此时已经激活了
					model.put("operateType", "actionEmail");
					model.put("operateResult", "error");
					model.put("content","该商户已经激活，此操作无效!");
				}
			}
		}
		return VIEW + "register";
	}
	
	/**
	 * 邮箱激活步
	 * @param request
	 * @param adminId
	 * @param model
	 * @return
	 */
	@RequestMapping("/stepTwo")
	@ResponseBody
	public RegisterResult registerStepTwo(HttpServletRequest request,Long adminId, ModelMap model){
		RegisterResult result = new RegisterResult();
		Admin admin = adminService.find(adminId);
		if(admin.getStep()==1){
			result.setType("error");
			result.setContent("您还没有激活");
			return result;
		}else if(admin.getStep()==2){
			result.setType("succ");
			result.setContent("激活成功");
			return result;
		}else{
			result.setType("redirect");
			result.setContent("数据已更新");
			return result;
		}
	}
	
	@RequestMapping("/stepThird")
	@ResponseBody
	public RegisterResult registerStepThird(HttpServletRequest request,Long adminId,Integer type, ModelMap model){
		RegisterResult result = new RegisterResult();
		Admin admin = adminService.find(adminId);
		if(admin.getStep()==2 || admin.getStep()==3){
			admin.setType(type);
			admin.setStep(3);
			adminService.update(admin);
			result.setType("succ");
			result.setContent("选择类型成功");
		}else if(admin.getStep() == 4 && !admin.getIsCheck()){
			admin.setType(type);
			admin.setStep(3);
			adminService.update(admin);
			result.setType("succ");
			result.setContent("选择类型成功");
		}else{
			result.setType("redirect");
			result.setContent("数据已更新");
		}
		return result;
	}
	
	/**
	 * 获取验证码
	 * 
	 * @param servletRequest
	 *            ServletRequest
	 * @return 验证码
	 */
	protected String getCaptcha(ServletRequest servletRequest) {
		return WebUtils.getCleanParam(servletRequest, captchaParam);
	}
	
	protected String getCaptchaId(ServletRequest servletRequest) {
		String captchaId = WebUtils.getCleanParam(servletRequest, captchaIdParam);
		if (captchaId == null) {
			captchaId = ((HttpServletRequest) servletRequest).getSession().getId();
		}
		return captchaId;
	}
	
	
	public void sendEmail(Admin admin){
		Mail mail = new Mail(true);
		String url = "http://fengkeworld.com/travel/pc/index/actionEmail.jhtml?id="+admin.getId()+"&Ticket="+admin.getTicket();
		//String url = "http://localhost:8089/fengke/travel/pc/index/actionEmail.jhtml?id="+admin.getId()+"&Ticket="+admin.getTicket();
		mail.doSendHtmlEmail("风客旅行供应商申请邮箱认证", "请点击以下链接进行激活<br/><a href=\""+url+"\">"+url+"</a>", admin.getEmail(), null);
	}
	
	
	
	public String encryptionTicket(String ptext){
		try {
			SecretKey skeySpec = new SecretKeySpec(keyBytes, "RC4");
			Cipher cipherEncrypt = Cipher.getInstance("RC4");
			cipherEncrypt.init(Cipher.DECRYPT_MODE, skeySpec);
			byte[] applyBytes = cipherEncrypt.doFinal(ptext.getBytes());//申请数据
			String decodeBase64 = (new BASE64Encoder()).encode(applyBytes);
			return decodeBase64;
    	} catch (Exception e) {
    		return new Date().getTime()+"";
		}
	}
	
	@RequestMapping(value = "/save", method = RequestMethod.POST)
	public String save(Admin admin,ImageFile imageFile, ModelMap model) {
		try {
			Admin persit =  adminService.find(admin.getId());
			if(persit.getStep()==3){
				admin.setIsEnabled(true);
				admin.setIsLocked(false);
				admin.setLoginFailureCount(0);
				admin.setLockedDate(null);
				admin.setLoginDate(null);
				admin.setLoginIp(null);
				admin.setOrders(null);
				admin.setPaperNum("system");
				if(admin.getType()==1){
					admin.setCompany("system");
				}else{
					admin.setCompany(admin.getCompanyName());
				}
				if(imageFile.getGzFile()!=null){
					String gzFilePath = saveImage(imageFile.getGzFile());
					admin.setGzImg(gzFilePath);
				}
				if(imageFile.getGrFile()!=null){
					String grFilePath = saveImage(imageFile.getGrFile());
					admin.setIdHandsImg(grFilePath);
				}
				if(imageFile.getZmFile()!=null){
					String zmFilePath = saveImage(imageFile.getZmFile());
					admin.setIdFrontImg(zmFilePath);
				}
				if(imageFile.getFmFile()!=null){
					String fmFilePath = saveImage(imageFile.getFmFile());
					admin.setIdBackImg(fmFilePath);
				}
				admin.setStep(4);
				admin.setReason("");
				adminService.update(admin,"company","ticket","registerTime", "id","username","password","email","type","isCheck","hasEmailAction","roles","orders","products");
			}else{
				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		model.put("saveSucc", true);
		return "/travel/pc/register";
		
	}
	
	/**
	 * 取得上传文件的后缀名
	 */
	public static String getExtensionName(String filename) {   
        if ((filename != null) && (filename.length() > 0)) {   
            int dot = filename.lastIndexOf('.');   
            if ((dot >-1) && (dot < (filename.length() - 1))) {   
                return filename.substring(dot + 1);   
            }   
        }   
        return filename;   
    }
	
	public String saveImage(MultipartFile file){

		MultipartFile multipartFile = file;
		if (multipartFile != null && !multipartFile.isEmpty()) {
			try {
				Setting setting = SettingUtils.get();
				Map<String, Object> model = new HashMap<String, Object>();
				model.put("uuid", UUID.randomUUID().toString());
				String uploadPath = FreemarkerUtils.process(setting.getImageUploadPath(), model);
				String uuid = UUID.randomUUID().toString();
				String sourcePath = uploadPath + uuid + "-source." + FilenameUtils.getExtension(multipartFile.getOriginalFilename());
				Collections.sort(storagePlugins);
				for (StoragePlugin storagePlugin : storagePlugins) {
					if (storagePlugin.getIsEnabled()) {
						File tempFile = new File(System.getProperty("java.io.tmpdir") + "/upload_" + UUID.randomUUID() + ".tmp");
						if (!tempFile.getParentFile().exists()) {
							tempFile.getParentFile().mkdirs();
						}
						multipartFile.transferTo(tempFile);
						Collections.sort(storagePlugins);
						for (StoragePlugin _storagePlugin : storagePlugins) {
							if (_storagePlugin.getIsEnabled()) {
								try {
									storagePlugin.upload(sourcePath, tempFile, file.getContentType());
								} finally {
									FileUtils.deleteQuietly(tempFile);
								}
								break;
							}
						}
						return storagePlugin.getUrl(sourcePath);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	
	/**
	 * 检查用户名是否被禁用或已存在
	 */
	@RequestMapping(value = "/check_username", method = RequestMethod.GET)
	public @ResponseBody
	boolean checkUsername(String username) {
		if (StringUtils.isEmpty(username)) {
			return false;
		}
		if (adminService.findByUsername(username) != null) {
			return false;
		} else {
			return true;
		}
	}
	
	/**
	 * 检查用户名是否被禁用或已存在
	 */
	@RequestMapping(value = "/check_email", method = RequestMethod.GET)
	public @ResponseBody
	boolean checkEmail(String email,Long adminId) {
		if (StringUtils.isEmpty(email)) {
			return false;
		}
		if(adminId!=null && adminId>0){
			Admin admin = adminService.find(adminId);
			if(admin.getEmail().equals(email)){
				return true;
			}
		}
		if (adminService.findByEmail(email) != null) {
			return false;
		} else {
			return true;
		}
	}
	
	/**
	 * 检查用户名是否被禁用或已存在
	 */
	@RequestMapping(value = "/check_captcha", method = RequestMethod.GET)
	public @ResponseBody
	boolean checkCaptcha(String captcha,String captchaId,Long adminId) {
		if(!captchaService.isValid(CaptchaType.adminLogin, captchaId, captcha)){
			return false;
		}
		return true;
	}
	
}